// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("./utils/checkAccuracy.js");

// ✅ 历史开奖数据
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

// ✅ 是否使用滑动窗口
const useWindow = true;

// ✅ 统计每个 windowSize 的表现
const windowStats = [];

// ✅ 外层循环 windowSize = 30 ~ 300
for (let windowSize = 5; windowSize <= 300; windowSize++) {
  // 初始化马尔科夫转移矩阵
  const transitionMatrix = {};
  allNumbers.forEach((from) => {
    transitionMatrix[from] = {};
    allNumbers.forEach((to) => {
      transitionMatrix[from][to] = 0;
    });
  });

  const predictResults = [];

  allValues.forEach((item, index) => {
    const temp = useWindow
      ? allValues.slice(Math.max(0, index - windowSize), index)
      : allValues.slice(0, index);

    if (temp.length === 0 || index === 0) return;

    const lastNumber = allValues[index - 1].number;
    const transitionRow = transitionMatrix[lastNumber];

    // 排序转移最多的 32 个号码作为预测
    const prediction = Object.entries(transitionRow)
      .sort((a, b) => b[1] - a[1])
      .map(([num]) => num)
      .slice(0, 32);

    predictResults.push(checkAccuracy(prediction, item.number));

    // 更新转移矩阵（不偷看答案）
    const prev = lastNumber;
    const curr = item.number;
    if (transitionMatrix[prev] && transitionMatrix[prev][curr] != null) {
      transitionMatrix[prev][curr]++;
    }
  });

  // 统计准确率和最大连续错误次数
  const total = predictResults.length;
  const correct = predictResults.filter((x) => x === 1).length;
  const accuracy = total > 0 ? ((correct / total) * 100).toFixed(2) : 0;

  let maxWrongStreak = 0;
  let currentStreak = 0;
  predictResults.forEach((res) => {
    if (res === 0) {
      currentStreak++;
      if (currentStreak > maxWrongStreak) {
        maxWrongStreak = currentStreak;
      }
    } else {
      currentStreak = 0;
    }
  });

  // 记录当前窗口结果
  windowStats.push({
    windowSize,
    accuracy: Number(accuracy),
    correct,
    total,
    maxWrongStreak,
  });
}

// ✅ 输出准确率最高的窗口
const best = _.maxBy(windowStats, "accuracy");

console.log("📈 马尔科夫策略 - 准确率最高结果：");
console.log(`Window Size: ${best.windowSize}`);
console.log(`准确率: ${best.accuracy}%`);
console.log(`命中次数: ${best.correct}/${best.total}`);
console.log(`最大连续错误次数: ${best.maxWrongStreak}`);

// ✅ 找出准确率最高的窗口
const best2 = _.maxBy(windowStats, "accuracy");
// ✅ 输出最佳准确率窗口
console.log("\n📈 准确率最高窗口结果：");
console.log(`Window Size: ${best2.windowSize}`);
console.log(`准确率: ${best2.accuracy}%`);
console.log(`最大连续错误次数: ${best2.maxWrongStreak}`);
console.log(`命中次数: ${best2.correct}/${best2.total}`);
